% $Header: /cvsroot/html2ps/postscript/box.block.ps,v 1.1 2005/12/18 07:21:36 Konstantin Exp $

/box-block-create {
  box-container-create

% Setup method references
  dup box-block-setup-methods
  dup /box-block add-type
} def

/box-block-reflow {                % => Content Parent This
  dup /position get-css-value
  {
    dup /static   eq { pop 3 copy /reflow-static   call-method   exit } if
    dup /relative eq { pop 3 copy /reflow-relative call-method exit } if
    dup /absolute eq { pop dup 3 index context-add-absolute-positioned exit } if
    dup /fixed    eq { pop dup 3 index context-add-fixed-positioned    exit } if
  } loop
  
  pop pop pop                      % => 
} def                              % => 

/box-block-reflow-absolute {       % => Context This
% Calculate actual box position relative to the containing block
  dup box-generic-get-containing-block
                                   % => Context This CBlock

  dup containing-block-left    % => Context This CBlock CBLeft
  2 index /left get-css-value add  % => Context This CBlock Left
  2 index put-left                 % => COntext This CBlock

% TODO: top percentage values

  dup containing-block-top
  2 index /top get-css-value
  /value get sub                   % => Context This CBlock Top
  2 index get-extra-top sub        % => Context This CBlock Top
  2 index put-top                  % => Context This CBlock

% As sometimes left/right values may not be set, we need to use the "fit" width here
% if no width constraints been set, it will not be modified by the code below

  2 index 2 index /get-max-width
  call-method                      % => Context This CBlock MW
  2 index put-full-width           % => Context This CBlock

% Update the width, as it should be calculated based upon containing block width, not real parent

  dup containing-block-right
  1 index containing-block-left
  sub                              % => Context This CBlock CBWidth
  2 index /get-width call-method   % => Context This CBlock CBWidth W
  3 index get-width-constraint
  wc-apply                         % => Context This CBlock W'
  2 index put-full-width           % => Context This CBlock

% And remove any width constraint after this, as they could refer to parent widths
  wc-create-none                   % => Context This CBlock WCNone
  2 index put-width-constraint     % => Context This CBlock

  2 index 2 index
  box-container-reflow-content     % => Context This CBlock

  pop pop pop
} def

/box-block-reflow-fixed {          % => Context This
  0 1 index put-left
  0 1 index put-top

% As sometimes left/right values may not be set, we need to use the "fit" width here
% if no width constraints been set, it will not be modified by the code below

  1 index
  1 index /get-max-width
  call-method
  1 index put-full-width           % => Context This

  dup /get-width call-method
  dup
  2 index get-width-constraint
  wc-apply
  1 index put-full-width           % => Context This

  wc-create-none 1 index
  put-width-constraint             % => Context This

  2 copy
  box-container-reflow-content
    
  pop pop 
} def

/box-block-reflow-relative {       % => Context Parent This
% CSS 2.1:
% Once a box has been laid out according to the normal flow or floated, it may be shifted relative 
% to this position. This is called relative positioning. Offsetting a box (B1) in this way has no
% effect on the box (B2) that follows: B2 is given a position as if B1 were not offset and B2 is 
% not re-positioned after B1's offset is applied. This implies that relative positioning may cause boxes
% to overlap. However, if relative positioning causes an 'overflow:auto' box to have overflow, the UA must
% allow the user to access this content, which, through the creation of scrollbars, may affect layout.

  3 copy
  box-block-reflow-static

% Note that percentage values are ignored for relative positioning

% Check if top value is percentage

  dup /top get-css-value /percentage get {
    0
  } {
    dup /top get-css-value /value get  
  } ifelse                         % => Context Parent This Top
  neg

  2 index /left get-css-value      % => Context Parent This Top Left
  2 index /offset call-method      % => Context Parent This 

  pop pop pop
} def

/box-block-reflow-static {         % => Context Parent This
  dup /float get-css-value
  /none eq {
    3 copy /reflow-static-normal call-method
  } {
    3 copy /reflow-static-float  call-method
  } ifelse
  pop pop pop
} def

/box-block-reflow-static-normal {  % => Context Parent This
  1 index /null ne {
% By default, child block box will fill all available parent width;
% note that actual width will be smaller because of non-zero padding, border and margins
    1 index /get-width call-method
    1 index put-full-width

% calculate margin values if thy have been set as a percentage
    1 index 1 index box-generic-calc-percentage-margins

% calculate width value if it had been set as percentage
    2 index 2 index 2 index box-generic-calc-percentage-width

% calculate 'auto' values of width and margins
% unline tables, DIV width is either constrained by some CSS rules or 
% expanded to the parent width; thus, we can calculate 'auto' margin 
% values immediately
    1 index 1 index box-generic-calc-auto-width-margins

    3 copy box-generic-collapse-margin % => Context Parent This Y

% At this moment we have top parent/child collapsed margin at the top of context object
% margin stack

% Apply 'clear' property

    3 index exch 2 index           % => Context Parent This Context Y This
    box-generic-apply-clear        % => Context Parent This Y

% Store calculated Y coordinate as current Y in the parent box
    2 index put-current-y          % => Context Parent This
    
% Terminate current parent line-box
    2 index
    2 index
    box-container-close-line

% And add current box to the parent's line-box (alone)
    dup 2 index box-container-append-line

% Note that top margin already used above during margin collapsing
    1 index get-current-y
    1 index get-border-top-width sub
    1 index get-padding-top sub    % => Context Parent This Y

    2 index get-left
    2 index get-extra-left add     % => Context Parent This Y X

    2 index box-generic-move-to    % => Context Parent This
  } if

% Reflow contents
  2 index 1 index                  % => Context Parent This Context This
  box-container-reflow-content     % => Context Parent This

% After reflow_content we should have the top stack value replaced by the value
% of last child bottom collapsed margin

  dup box-container-get-first /null ne {
    2 index context-get-collapsed-margin
  } {
    0
  } ifelse
  1 index get-margin-bottom
  max                              % => Context Parent This max(cm,bm)

  3 index context-pop-collapsed-margin
  3 index context-pop-collapsed-margin
  3 index context-push-collapsed-margin
                                   % => Context Parent This

  1 index /null ne {
% Extend parent's height to fit current box
    1 index get-uid
    3 index context-container-uid eq {
      dup get-bottom-margin
      2 index box-generic-extend-height
    } {
      dup get-bottom-border
      2 index box-generic-extend-height
    } ifelse                       % => Context Parent This

    2 index 2 index
    box-container-close-line

% Then shift current flow position to the current box margin edge
    dup get-bottom-border
    3 index context-get-collapsed-margin sub
    2 index put-current-y
  } if                             % => Context Parent This

  3 copy
  box-generic-check-page-break-after
  
  pop pop pop
} def

/box-block-setup-methods {         % => Box
  dup get-box-dict /Methods get    % => Box Methods
  dup /reflow               {box-block-reflow} put
  dup /reflow-absolute      {box-block-reflow-absolute} put
  dup /reflow-relative      {box-block-reflow-relative} put
  dup /reflow-static        {box-block-reflow-static} put
  dup /reflow-static-normal {box-block-reflow-static-normal} put
  pop pop
} def

/box-block-show-fixed {            % => Viewport Box
  1 index viewport-get-left
  1 index /left get-css-value add  % => Viewport Box Left
  
  2 index viewport-get-top
  2 index /top get-css-value
  /value get sub                   % => Viewport Box Left Top

  exch

  2 index box-generic-move-to      % => Viewport Box

  2 copy /show call-method

  pop pop
} def